iT邦幫忙

第 11 屆 iThome 鐵人賽

1

上一篇文章介紹了 SOA (Service-Oriented Architecture) 的遠大願景與淡淡哀傷的下場,而這一篇要講的是 SOA 在平行宇宙的成功版本:Microservices

Microservices 是近幾年來軟體工程領域裡滿常聽到的熱門關鍵字之一。大概是在 SOA 出現後幾年開始崛起,跟 SOA 其實有 87% 像,所以最一開始 microservices 出現的時候,都還是被與 SOA 一同稱呼。兩者想要做的都是將一個單體式架構(Monolithic Architecture)依照功能拆成小塊,達到更好的可重用性(reusability)靈活度(flexibility)

那 SOA 跟 Microservices 差在哪裡?

SOA 與 Microservices 之間最大的差別是 SOA 一開始是以一個純然概念性的姿態出現的,而 Microservices 則是從幾個公司(Netflix, Amazon 等等)自己內部實做的架構慢慢歸納的模式,可以說前者是由上到下,後者是由下到上的演變。當初 SOA 會衰落,就是因為遇到許多理論到實作上面的困難/分歧,而 Microservices 則因為是從成功的先例開始,所以實作上比較容易取得共識,並且 Microservices 涵蓋的範圍很廣,除了技術之外,模式、原則、文化、組織特徵都包含於內,是一個發展成熟的體系。

本篇文章會從 Microservices 與 Monolithic Architecture 的比較來切入,介紹 Microservices 的特徵與實作原則,再來分析在什麼樣的情況下,使用哪種架構會更加合適。開始吧!

Microservices vs Monolithic Architecture

目前單體式架構(Monolithic Architecture)仍然是主流的軟體架構。單體式架構是什麼呢?簡單來說就是一個「一站式」的應用程式—一個請求到回應的過程中,經過的各式各樣**元件(component)**都放在同一個地方(用同一個語言、在同一個地方部署)。

Microservices 則是一種將不同元件從一個大統一的架構中拆出來的模式。比如說,原本在一個 Monolithic Application 中有用戶認證、髒話過濾、圖片壓縮等等元件,這些元件的存在形式會是插件(plugin)或是函式庫(library),而在 Microservices 的架構中,就會是一個個服務(service)。

Libraries and Services

一個引入許多 libraries 跟一個由許多不同 microservices 所組成的應用程式有什麼不一樣?第一,當你改動一個 library,哪怕只是一小部分,你都必須要重新部署整個應用程式,而如果是使用 microservices,你只要重新部署該服務就好了。相信使用 monolithic architecture 的人都有過這種覺得很麻煩的經驗:明明就只改了一行的程式碼,卻要讓整個應用程式重新跑一系列的測試部署流程......

再來,當我們使用 libraries 時它會被我們載入記憶體中,成為一個 function call。當我們使用一個 service,它則是在這個程序(process)之外的元件,必須使用 web service request 或是 remote procedure call 來溝通。

Microservices vs Modularization

如果單純將一個 Monolithic application 模組化(modularized)呢?實務上,這會碰到幾個困難點:

  1. 這些模組通常會傾向被包進太多的 context—這會導致開發上的困難,因為這些模組之間的交互關係不是有明確規範的,所以開發人員必須要自己記得模組與模組之間的關係,當應用程式變大或是時間屹久就會變得沒有效率。
  2. 這些模組通常界線很難分明。

這些難處只有良好的 documentation 與 discipline 才能好好預防。

那 service 的好處是什麼?因為它必須要依靠 web service request 或是 remote procedure call,這強迫我們為每個元件訂出清楚明確的界線,並且讓服務與服務之間有一致的介面。有了這個強而有力的限制我們就再也不用依賴開發者的良心發現(?)來確保架構(這一方面)的品質了。

Microservices Implementation

Microservices 是一個包山包海的概念,因此一不小心就可能會讓它變得模糊而難以捉模。以下介紹一些重要的 microservices 實作原則。

Smart endpoints, dumb pipes.

這是一個 SOA 與 Microservices 很不同的點:記得上一篇講到的 ESB (Enterprise Service Bus) 嗎?ESB 讓 SOA 的架構變得非常中心化,所有的服務都與 ESB 有高度依存關係。Microservices 則是相反:它強調每個服務之間的溝通管道應該要越笨越好(知道越少越好),而所有的溝通的知識都應該在元件本身裡面。

兩個最常被 Microservices 使用的 protocol 是 HTTP (request-response with resource API) 還有 lightweight messaging。前者非常的 cache-friendly (?) ,常常被使用到的 resource 可以被輕易地快取。至於第二種方法,則常常使用像是 RabbitMQ 或是 ZeroMQ 。這些機制都只是提供一個訊息傳遞的路由器(message router),自己並不會保留資訊,而資訊都存在於 endpoint 中。

Database Decentralization

除了 conceptual model 的去中心化,Microservices 也將資料儲存去中心化。通常每個服務都會有自己的資料庫—可以是同一個資料庫結構的不同實例,也可以是完全不同的資料庫系統。

Organization / Mindset

Microservices 跟傳統分工方法不一樣。原本一個團隊可能會將工程部門分成 operations, backend, UI 等等—依照「功能」區分。如果是從服務出發的思維,則每一個 service team 都會是一個獨立的,自給自足的小宇宙,會有自己的 User Interface, Persistent Storage, Project Management 等人才,是跨功能的。當我們需要改動一個元件時,我們不用「跨組」溝通,只需要找組內的人協調就好了。

使用 Microservices 需要謹慎考量的事

雖然 microservices 聽起來很理想,但同時它也存在需要我們小心處理的眉角與挑戰。

expensive calls

將原本放在一起的元件拆分成一個個獨立的 service,會讓每次訊息傳遞的成本變大。這也是為什麼一個 service 的粒度通常會比 library 還要大。

complicated composition

另一個微服務的挑戰是如何為每個服務畫出清楚合理,並且符合軟體需要的界線。如果元件之間的關係設計不妥,那麼就只是將複雜性從內部搬到外部而已,若是服務需要重構,那麼這會比使用 in-memory library 來得複雜許多。(想想將程式碼在獨立的服務之間搬移—不是一件好玩的事吧)。

eventual consistency

由於 microservices 的資料管理是去中心化的,一筆資料需要更新,處理與呈現可能是兩個不同的 service,於是就會出現一段資料不一致的空窗期。比如說,當你更新一筆資料時,送出後網頁自動重新整理,但是資料卻要在你再次重新整理頁面後才會被更新。

多按一次重新整理還是小事,但是當企業因為不一致的資料作出不正確的判斷/決策時,就不是一件可以被忽略的事了。

不過這不是說 monolithic architecture 就沒有 eventual consistency 的問題(尤其當快取進來玩的時候...)。只是在 microservices 中,這是一個必須更加謹慎對待的題目。

什麼樣的情況下適合使用 Microservices?

Don't even consider microservices unless you have a system that's too complex to manage as a monolith.

– Martin Fowler, Microservice Premium

這張圖很清楚完整的解釋了這一點。
microservice vs monolith in productivity
(取自 https://martinfowler.com/bliki/images/microservice-verdict/productivity.png)

對大多數的專案而言,monolith 還是一個比較適合的架構。microservices 的威力只在於當專案複雜度非常高,以至於維護 monolithic architecture 變得很吃力的時候才會顯現,因為要設計出一個能夠運作良好、職責分明的 microservices 架構,需要投注的心力不容小覷。

儘管如此,我們仍然要記得不管是不是 microservices,模組化都是一個我們可以謹記在心的目標。只要有良好的模組化,就算是 monolithic architecture,還是能夠享受高維護性與彈性的好處。

Reference

作者:Jenny


上一篇
[Architectural Pattern] 服務導向架構 Service-Oriented Architecture 波折的一生
下一篇
The gentlest introduction to the Programming Pattern known as “monads”
系列文
什麼?又是/不只是 Design Patterns!?32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言